<?php
/*
 * ebiz front
 *
 * CategoryService Service
 *
 * @author allen
 *
 */

require_once '../app/core/services/BaseService.php';
require_once '../app/models/CategoryDao.php';
require_once '../app/models/CategoryProductDao.php';
require_once '../app/models/ProductDao.php';
require_once '../app/models/ProductItemDao.php';
require_once '../app/util/CommonUtil.php';
require_once '../app/util/Pager.php';
require_once '../app/models/PromotionDao.php';
require_once '../app/constants/ConfigConstants.php';

require_once '../app/models/MetadataDao.php';
require_once '../app/models/MetadataOptionDao.php';
require_once '../app/models/SpecialProductItemDao.php';

class CategoryService extends BaseService
{

    private $commonUtil;
	private $categoryDao;
	private $categoryProductDao;
	private $productDao;
	private $productItemDao;
	private $promotionDao;

    private $metadataDao;
    private $metadataOptionDao;
    private $specialProductItemDao;

	public function __construct(){
		parent::__construct();
		$this->commonUtil = new CommonUtil();
		$this->categoryDao = new CategoryDao($this->dbUtil);
		$this->categoryProductDao = new CategoryProductDao($this->dbUtil);
		$this->productDao = new ProductDao($this->dbUtil);
		$this->productItemDao = new ProductItemDao($this->dbUtil);
		$this->promotionDao = new PromotionDao($this->dbUtil);

        $this->metadataDao = new MetadataDao($this->dbUtil);
        $this->metadataOptionDao = new MetadataOptionDao($this->dbUtil);
        $this->specialProductItemDao = new SpecialProductItemDao($this->dbUtil);
        $this->specialProductItemDao = new SpecialProductItemDao($this->dbUtil);

	}

	public function getByUrlTitle($urltitle){
		$categories = $this->categoryDao->getByUrlTitle($urltitle);
		return $categories;
	}

	/*test of generate menu*/////this is ok

	public function getAllCategory($parentId){
		$categories = $this->categoryDao->getAllcategory();
		$result = $this->categoryCreateTree($categories, $parentId);
		return $result;
	}

	public function getOneCategory($categories, $parentId){
		$result = array();
		foreach ($categories as $category) {
			if($category['parent_id'] == $parentId){
				$result[] = $category;
			}
		}
		return $result;
	}

    public function categoryCreateTree($categories, $parentId){
        $upc = array();
        $childCategory = $this->getOneCategory($categories, $parentId);
        if(!empty($childCategory)){
            foreach($childCategory as $category){
                $tempUpc = array();
                $tempUpc['id'] = $category['id'];
                $tempUpc['shortName'] = $category['short_name'];
                $tempUpc['fullName'] = $category['full_name'];
                $tempUpc['urlTitle'] = $category['url_title'];
                $child = $this->categoryCreateTree($categories, $category['id']);
                $tempUpc['child'] = $child;
                $upc[] = $tempUpc;
            }
        }
        return $upc;
    }

	/*test of generate menu*/

    public function generateBreadCrumb($urlTitle){
        $category = $this->categoryDao->getByUrlTitle($urlTitle);
        $cid = $category[0]['id'];
        $categories = array();
        $categories = $this->createTreeForBreadCrumb($cid);
        $result = self::generateBreadCrumbHtml($categories);
        return $result;
    }

    public function createTreeForBreadCrumb($id){  //search category if itself has father category//$Id is the child category parent id
        $upc = array();
        $fatherCategory = $this->categoryDao->getById($id);
        if(!empty($fatherCategory)){
            foreach($fatherCategory as $category){
                $tempUpc = array();
                $tempUpc['id'] = $category['id'];
                $tempUpc['shortName'] = $category['short_name'];
                $tempUpc['fullName'] = $category['full_name'];
                $tempUpc['urlTitle'] = $category['url_title'];
                $father = $this->createTreeForBreadCrumb($category['parent_id']);
                $tempUpc['father'] = $father;
                $upc[] = $tempUpc;
            }
        }
        return $upc;
    }

    public function generateBreadCrumbHtml($categories){
        $html = "";
    	$shortName = self::generateBreadCrumbShortName($categories);
    	$urlTitle = self::generateBreadCrumbUrlTitle($categories);
    	$shortNameArray = explode(',', $shortName);
    	$urlTitleArray = explode(',', $urlTitle);
    	for($i = 0; $i < count($shortNameArray); $i++){
    		$html .= "<a href='http://".ConfigConstants::$domainPath."/c/".$urlTitleArray[$i]."'>".$shortNameArray[$i]."</a>";
    		$html .= "&raquo;";
    	}
    	$html = substr($html, 0, strlen($html) - 7);//note!!!
    	return $html;
    }

    public function generateBreadCrumbShortName($categories){
        $html = "";
    	if(!empty($categories)){
            foreach($categories as $category){
                $name = $category['shortName'];
                $father = $category['father'];
                if(!empty($father)){
                    $html .= $this->generateBreadCrumbShortName($father).",";
                }
            }
            $html .= $name;
        }
        return $html;
    }

    public function generateBreadCrumbUrlTitle($categories){
        $html = "";
    	if(!empty($categories)){
            foreach($categories as $category){
                $urlTitle = $category['urlTitle'];
                $father = $category['father'];
                if(!empty($father)){
                    $html .= $this->generateBreadCrumbUrlTitle($father).",";
                }
            }
            $html .= $urlTitle;
        }
        return $html;
    }

    /////////////////////////////////////////

    public function createTree($parentId){  //search category if itself has children//$parentId is the father category id
    	$upc = array();
        $childCategory = $this->categoryDao->getByParentId($parentId);
        if(!empty($childCategory)){
        	foreach($childCategory as $category){
        		$tempUpc = array();
        		$tempUpc['id'] = $category['id'];
        		$tempUpc['shortName'] = $category['short_name'];
        		$tempUpc['fullName'] = $category['full_name'];
        		$tempUpc['urlTitle'] = $category['url_title'];
                $child = $this->createTree($category['id']);
        		$tempUpc['child'] = $child;
        		$upc[] = $tempUpc;
        	}
        }
        return $upc;
    }

    public function printTree($categories,$sep){    //output the result such as tree model
        if(!empty($categories)){
            foreach($categories as $category){
                $name = $category['shortName'];
                echo $name . $sep;
//                echo "<br/>";
                $children = $category['child'];
                if(!empty($children)){
                    $this->printTree($children, $sep);
                }
            }
        }
    }

    public function generateMenuHtml($categories){    //output the result as html model//add in 0616
        $html = "<ul> \n";
    	if(!empty($categories)){
            foreach($categories as $category){
                $children = $category['child'];
                if(!empty($children)){
	                $html .= "<li><a class='hide' href='http://".ConfigConstants::$domainPath."/c/".$category['urlTitle']."'>".$category['shortName']."</a> \n";
	                $html .= "<!--[if lte IE 6]> \n";
	                $html .= "<a href='http://".ConfigConstants::$domainPath."/c/".$category['urlTitle']."'>".$category['shortName']." \n";
	                $html .= "<table><tr><td> \n";
	                $html .= "<![endif]--> \n";
                    $html .= $this->generateMenuHtml($children);
	                $html .= "<!--[if lte IE 6]> \n";
	                $html .= "</td></tr></table> \n";
	                $html .= "</a> \n";
	                $html .= "<![endif]--> \n";
                }else{
                	$html .= "<li><a href='http://".ConfigConstants::$domainPath."/c/".$category['urlTitle']."' >".$category['shortName']."</a> \n";
                }
                $html .= "</li> \n";
            }
            $html .= "</ul> \n";
        }
        return $html;
    }

    public function getAllCategoryId($categories){  //get the categoryId and separated by ',' , format to string
        $cids = "";
        if(!empty($categories)){
            foreach($categories as $category){
                $id = $category['id'];
                $cids .= $id.",";
                $children = $category['child'];
                if(!empty($children)){
                    $cids .= $this->getAllCategoryId($children);
                }
            }
        }
        return $cids;
    }

    public function getAllProductId($products){  //get the productIds and separated by ',' , format to string, used in getProductItemByUrlTitle
        $pids = "";
        if(!empty($products)){
            foreach($products as $product){
                $id = $product['id'];
                $pids .= $id.",";
            }
        }
        return $pids;
    }

    public function getAllCategoryIdToArray($categories){  //get the categoryId o array
        $upc = array();
        if(!empty($categories)){
            foreach($categories as $category){
            	$temp = array();
                $temp['id'] = $category['id'];
                $temp['shortName'] = $category['shortName'];
                $children = $category['child'];
                if(!empty($children)){
                    $upc[] = $this->getAllCategoryIdToArray($children);
                }
                $upc[] = $temp;
            }
        }
        return $upc;
    }

    public function getProductItemByUrlTitle($urlTitle, $pagenumber, $path, $pagesize){   //in category Service to find product item
//    public function getProductItemByUrlTitle($urlTitle, $pagenumber, $path){   //in category Service to find product item
    	$route = $path;    //ex: c/dress/ ,c is category ,dress this is category sort
    	$category = $this->categoryDao->getByUrlTitle($urlTitle);  //the url title is only one
    	$cid = isset($category[0]['id']) ? $category[0]['id'] : 0;     //get the father category id , only one
    	$componentName = isset($category[0]['component_name']) ? $category[0]['component_name'] : "";      //get the category component file name
    	$categoryFullName = $category[0]['full_name'];//use in category view
    	$categoryUrlTitle = $category[0]['url_title'];//use in bread crumb category view
    	$categorySeoInfo = array($category[0]['seo_title'], $category[0]['seo_keyword'], $category[0]['seo_description']);
    	$result = $this->createTree($cid);     //base on cid generate the children info of the current cid
    	//0716 modify//only read once DB base on category url title to get the all item info//if click father category and itself have children
//    	$result = $this->getAllCategory($cid);     //base on cid generate the children info of the current cid
        $categoryIds = $this->getAllCategoryId($result);    //generate the cids separate by the ','
        $arr = array();
        $arr = $categoryIds.$cid;   //delete the last sign ','
        $arr = $this->categoryProductDao->getByAllCategoryIds($arr);
        $productIds = "";
        foreach ($arr as $product) {
        	$productIds .= $product['product_id'].",";
        }
        $productIds = $this->commonUtil->formatCategoryId($productIds);
        $productTotalCount = count($this->productDao->getAllByPids($productIds));   //get the page count
        $productInfos = $this->productDao->getByPids($productIds, $pagenumber, $pagesize);   //get the product info from products and product_items table through pids
        $pager = new Pager();
        $headerPaginate = $pager->paginate($pagenumber, $productTotalCount, $route, $pagesize);
//        $headerPaginate = $pager->paginate($pagenumber, $productTotalCount, $route);
        $result = array();
        $result[] = $headerPaginate;
        $result[] = $productInfos;
        $result[] = $componentName;//get the component file name from DB
        $result[] = $categoryFullName;//use in category image's alt attribute of category page
        $result[] = $categoryUrlTitle;//use in category bread crumb
        $result[] = $categorySeoInfo;//use in category title and meta
        return $result;
    }

//    public function showMenuInCatrgoryLeft(){   //dawei delete 0713
//        $category = new CategoryService();
//        $parentId = "0";
//        $result = $category->createTree($parentId);
//        return $result;
//    }

    //give the category id to get the all item id
    public function getItemIdByCategoryId($parentId){
        $result = $this->createTree($parentId);
        $cid = $this->getCategoryId($result);
        $cids = $cid.$parentId;//with their own input category id
        $item = $this->getItemId($cids);
        return $item;
    }

    public function getCategoryId($categories){    //output the result such as tree model
        $cid = "";
    	if(!empty($categories)){
            foreach($categories as $category){
                $cid .= $category['id'].",";
            	$children = $category['child'];
                if(!empty($children)){
                    $cid .= $this->getCategoryId($children);
                }
            }
        }
        return $cid;
    }

    public function getItemId($cids){
    	$itemId = array();
    	$itemInfo = $this->productItemDao->getItemInfoByCategoryIds($cids);
    	foreach ($itemInfo as $item){
    		$itemId[] = $item['itemId'];
    	}
    	return $itemId;
    }

    public function getComponentName($urlTitle){
        $result = $this->categoryDao->getByUrlTitle($urlTitle);
        $componentName = isset($result[0]['component_name']) ? $result[0]['component_name'] : "";
        return $componentName;
    }

    /**
     * get the promotion title from promotion table to show in product page when shipping_type = 1
     */
    public function getPromotionTitle(){
        $result = $this->promotionDao->getPromotionInfo();
        $promotionTitle = isset($result[0]['name']) ? $result[0]['name'] : "";
        return $promotionTitle;
    }

//    public function getCid($parentId){
//        $upc = array();
//        $childCategory = $this->categoryDao->getByParentId($parentId);
//        if(!empty($childCategory)){
//            foreach($childCategory as $category){
//                $tempUpc = array();
//                $tempUpc['id'] = $category['id'];
//                $child = $this->getCid($category['id']);
//                $tempUpc['child'] = $child;
//                $upc[] = $tempUpc;
//            }
//        }
//        return $upc;
//    }


//    public function getCategoryMenuByUrlTitle($urlTitle){   //in category service to find category menu
//        $category = $this->categoryDao->getByUrlTitle($urlTitle);
////        $cid = $category[0]['id'];
//        $cid = isset($category[0]['id']) ? $category[0]['id'] : 0;
//        $result = $this->createTree($cid);
//      return $result;
//    }

    //for akimimi
    /**
     * filter function for category page
     */
    public function getMetadataBySet($setId){
        $metadatas = $this->metadataDao->getMetadataBySet($setId);
        $i = 0;
        for($i; $i < count($metadatas); $i++){
            $inputType = $metadatas[$i]['input_type'];
            $metadataId = $metadatas[$i]['id'];
            if($inputType == 3 || $inputType == 4){
                $metadataOptions = $this->metadataOptionDao->getOptionsByMetadataId($metadataId);
                $metadatas[$i]['options'] = $metadataOptions;
            }
        }
        return $metadatas;
    }

    public function generateFilterByUrlTitle($urlTitle){
    	$categories = self::getByUrlTitle($urlTitle);
    	$setId = $categories[0]['metadata_set_id'];
    	$metadatas = self::getMetadataBySet($setId);
    	return $metadatas;
    }

    /**
     * 根据categories.id返回全部metadatas.input_type=3 && metadatas.in_basic_search=1 && metadata_options.is_delete=0的数据
     * 同时将数据整理为二维数组。形如
     * array( '0' => array('metadata_id'=>1, 'options'=>array('option_id'=>1)) )
     *
     * @param int $int_id
     * @return array
     */
    public function getMeatadatasByCategoryId($int_id) {
        $arr_datas = $this->metadataDao->getMetadatasByCategoryId($int_id);
        $arr_results = array();
        if (empty($arr_datas))
            return $arr_results;
        $arr_metadatas = array();
        foreach ($arr_datas as $int_key => $arr_data) {
            if( !isset($arr_metadatas[$arr_data['metadata_id']]) ){
                $arr_metadatas[$arr_data['metadata_id']] = $arr_data;
                $arr_metadatas[$arr_data['metadata_id']]['options'] = array();
            }
            $arr_metadatas[$arr_data['metadata_id']]['options'][] = $arr_data;
        }
        return $arr_metadatas;
    }

    public function getProductItemsByCategoryId(&$int_nowpage, &$int_rows, $int_id, $arr_filter, $arr_sortby, $str_otherFilter){
        $arr_metadataset = $this->metadataDao->getMetadatasetByCategoryId($int_id);
        if (empty($arr_metadataset[0])){
            HttpUtil::renderError( 'Throws is ' . __FILE__ . '[' . __LINE__ . ']' );
        }
        $int_metadatasetId = $arr_metadataset[0]['id'];
        $str_autoMetadataTableName = "`auto_metadata_set_{$int_metadatasetId}`";//获取自动索引表名称
        $arr_autoMetadataTableColumns = $this->metadataDao->getColumnsFromTable($str_autoMetadataTableName);//获取自动索引表中的字段
        $arr_metadatas = $this->metadataDao->getMetadataIdsByMetadatasetId($int_metadatasetId);//获取metadata_set下的所有metadata
        if (empty($arr_metadatas)){
            HttpUtil::renderError( 'Throws is ' . __FILE__ . '[' . __LINE__ . ']' );
        }
        foreach ($arr_metadatas as $arr_metadata) {
        	$str_autoMetadataTableColumnName = "auto_metadata_{$arr_metadata['id']}";//生成metadata_id所对应的字段的名字
        	if (!in_array($str_autoMetadataTableColumnName, $arr_autoMetadataTableColumns)){
                HttpUtil::renderError( 'Throws is ' . __FILE__ . '[' . __LINE__ . ']' );
        	    return false;//如果这个字段没有在自动索引表中定义那么返回false
        	}
        }
        /**
         * @desc 创建自动索引表查询使用的筛选条件
         */
        $str_filter = '';
        if (!empty($arr_filter)){
            foreach ($arr_filter as $str_key => $int_value) {
            	if( !empty($int_value) ){
            	    $str_filter.= " AND `a`.`{$str_key}` = '{$int_value}' ";
            	}
            }
        }
        $str_filter .= $str_otherFilter;
        /**
         * @desc 创建自动索引表使用的排序方式
         */
        if (!empty($arr_sortby['created'])) {
            $str_sortby = '`pi`.`created`' . ($arr_sortby['price']<0?' DESC':'');
        }elseif (!empty($arr_sortby['price'])) {
            $str_sortby = '`pi`.`sale_price`' . ($arr_sortby['price']<0?' DESC':'');
        }else{
            $str_sortby = '`pi`.`id`';
        }
        $int_rows = $this->productItemDao->getProductItemsByMetadatasetId($int_metadatasetId, null, null, null, $str_filter, true);
        /**
         * @desc 检查分页设置
         */
        Pager::ValidateNowPage($int_nowpage, $int_rows);
        $int_limit = Pager::GetPageLimitStartNumber($int_nowpage);
        $int_pagesize = Pager::GetDefaultPagesize();
        $arr_results = $this->productItemDao->getProductItemsByMetadatasetId($int_metadatasetId, $int_limit, $int_pagesize, $str_sortby, $str_filter);
        if(empty($arr_results))
            return array();
        /**
         * @desc 获取ProductItem属性
         */
//        require_once '../app/services/OrderService.php';
//        $orderService = new OrderService();
//        foreach ($arr_results as $int_key => $arr_product){
//            $arr_results[$int_key]['attributes'] = $orderService->getItemAttribute($arr_product['product_item_id']);
//        }
        return $arr_results;
    }

    /**
     * 获得指定category的全部上级
     *
     * @example
        <code>
        $arr_category = $categoryService->getParentCategory(100);
        while($arr_category=array_pop($this->navigation)){
            if(!empty($this->navigation))
                $arr_navsetting[] = array('url'=>'/c/'.$arr_category['id'], 'text'=>$arr_category['short_name']);
            else
                $arr_navsetting[] = array('text'=>$arr_category['short_name']);
        }
        </code>
     * @param int $int_id
     * @param array $arr_categorys 在调用时该值必须省略
     * @return array 返回结果[0]为指定的category，[1]为其父级....[N]为顶级
     */
    public function getParentCategory($int_id, $arr_categorys = null){
        if(empty($arr_categorys))
            $arr_categorys = array();
        $arr_category = $this->categoryDao->getById($int_id);
        if(empty($arr_category[0])){
            HttpUtil::renderError('Bad category path.');
            exit;
        }
        array_push($arr_categorys,$arr_category[0]);
        if($arr_category[0]['parent_id'] > 0)
            return $this->getParentCategory($arr_category[0]['parent_id'],$arr_categorys);
        return $arr_categorys;
    }

    /**
     * get product details by type
     * @param $type
     */
    public function getSpecialProductByType($type){
    	return $this->specialProductItemDao->getProductItemsByType($type);
    }
    /**
     *  searchController index functon use
     *  
     */
    public function getCategoryById($id){
 	    return $this->categoryDao->getById($id);
    }
}







